{
    //  业务开发中，存储原始数据
    let obj = {
        time: '2017-3-11',
        name: 'net',
        _r: 123
    }

    //  创建代理商，映射obj
    let monitor = new Proxy(obj, {
        //  拦截对象属性的读取
        get (target, key) {
            return target[key].replace('2017', '2018');
        },
        //  拦截对象设置属性
        set (target, key, value) {
            if (key === 'name') {
                return target[key] = value;
            } else {
                return target[key];
            }
        },
        //  拦截key in object操作
        has (target, key) {
            if (key === 'name') {
                return target[key];
            } else {
                return false;
            }
        },
        //  拦截delete
        deleteProperty (target, key) {
            if (key.indexOf('_') > -1) {
                delete (target[key]);
                return true;
            } else {
                return target[key];
            }
        },
        //  拦截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
        ownKeys (target) {
            return Object.keys(target).filter(item => item != 'time');
        }
    });

    //  用户访问，读取obj属性
    console.log('get', monitor.time);

    //  代理中set设置了只有name属性可修改
    monitor.time = 2018;
    monitor.name = 'Lay';
    console.log('set', monitor);

    //  判断属性是否存在obj
    console.log('has', 'name' in monitor, 'time' in monitor);

    //  删除time属性，失败；删除_r属性，成功
    // delete monitor.time;
    // console.log('delete', monitor)
    // delete monitor._r;
    // console.log('delete', monitor)

    console.log('ownKeys', Object.keys(monitor))
}

{
    let obj = {
        time: '2017-3-11',
        name: 'net',
        _r: 123
    }

    //  获取属性
    console.log('reflect', Reflect.get(obj, 'time'))

    //  设置属性
    Reflect.set(obj, 'name', 'Lay');
    console.log(obj);

    //  判断属性是否存在
    console.log('has', Reflect.has(obj, 'name'));
}

{
    function validator (target, validator) {
        return new Proxy(target, {
            _validator: validator,
            set (target, key, value, proxy) {
                if (target.hasOwnProperty(key)) {
                    let va = this._validator[key];
                    if (!!va(value)) {
                        return Reflect.set(target, key, value, proxy);
                    } else {
                        throw Error(`不能设置${key}到${value}`);
                    }
                } else {
                    throw Error(`${key} 不存在`);
                }
            }
        })
    }

    const personValidators = {
        name (val) {
            return typeof val === 'string'
        },
        age (val) {
            return typeof val === 'number' && val > 18
        }
    }

    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
            return validator(this, personValidators);
        }
    }

    const person = new Person('Lay', 30);
    console.log(person);

    person.name = 'Han Mei Mei';
    console.log(person);
}